import base64
import pickle

from django.conf import settings
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.generics import ListAPIView, RetrieveAPIView, CreateAPIView, UpdateAPIView
from rest_framework.permissions import IsAuthenticated
from random import randint
from threading import Thread
from django_redis import get_redis_connection  # 连接缓存数据库
from rest_framework_jwt.views import ObtainJSONWebToken

from carts.utils import merge_cart_cookie_to_redis
from meiduo_mall.libs.yuntongxun.sms import CCP
from celery_tasks.sms_code.tasks import send_sms_code
from users.models import User
from users.serializers import UserSerializer, UserDetailSerializer, UserEmailSerializer
from itsdangerous import TimedJSONWebSignatureSerializer as TJS


# Create your views here.

# def send_sms_code(mobile, sms_code):
#     ccp = CCP()
#     ccp.send_template_sms(mobile, [sms_code, '1'], 1)  # 耗时操作，设置多线程,进行异步执行


class SMSCodeView(APIView):
    '''发送短信验证码'''

    def get(self, request, mobile):
        # 生成一个短信验证码
        sms_code = "%06d" % randint(0, 999999)
        print(sms_code)
        # 保存短信验证码
        coon = get_redis_connection('verify')  # 建立连接，生成一个连接对象

        # 判断前端的请求间隔是否在60秒之内
        flag = coon.get('sms_code_flag%s' % mobile)
        if flag:
            return Response({'error': '请求过于频繁'})

        # redis 管道的使用(当进行写入操作时，使用管道)
        pl = coon.pipeline()
        pl.setex('sms_%s' % mobile, 300, sms_code)  # 保存方式

        # 写入一个标志数据
        pl.setex('sms_code_flag%s' % mobile, 60, 1)

        # 执行
        pl.execute()

        # 发送短信验证码
        # ccp = CCP()
        # ccp.send_template_sms(mobile,[sms_code,'1'],1)      #耗时操作，设置多线程,进行异步执行
        # 线程异步执行发送短信,解决耗时操作
        # th = Thread(target=send_sms_code, kwargs={'mobile':mobile,'sms_code':sms_code})
        # th.start()

        # 使用celery
        send_sms_code.delay(mobile, sms_code)

        # 返回结果
        return Response({'message': 'ok'})


class UserNameView(APIView):
    '''
        判断用户名是否重复
    '''

    def get(self, request, username):
        # 获取前端数据

        # 验证判断
        count = User.objects.filter(username=username).count()

        return Response({
            'count': count,
        })


class MobileView(APIView):
    '''
        判断手机号是否重复
    '''

    def get(self, request, mobile):
        # 获取前端数据

        # 验证判断
        count = User.objects.filter(mobile=mobile).count()

        return Response({
            'count': count,
        })


class UserView(CreateAPIView):
    '''
        注册用户
    '''
    serializer_class = UserSerializer


class UserDetialView(RetrieveAPIView):
    '''
        用户详情
    '''
    serializer_class = UserDetailSerializer
    # queryset = User.objects.all()

    # 添加用户认证
    permission_classes = [IsAuthenticated]

    # 重写get_object方法
    def get_object(self):
        return self.request.user


class UserEmailView(UpdateAPIView):
    '''
        保存用户邮箱
    '''
    serializer_class = UserEmailSerializer
    # 用户认证
    permission_classes = [IsAuthenticated]

    def get_object(self):
        return self.request.user


class UserEmailVerifyView(APIView):
    '''
        验证邮箱
    '''

    def get(self, request):
        # 1,获取前端数据
        token = request.query_params.get('token')
        # 2,解密token
        tjs = TJS(settings.SECRET_KEY, 300)
        try:
            data = tjs.loads(token)
        except:
            return Response({'error': '错误的token'}, status=400)

        # 3,获取解密后的用户数据
        username = data.get('username')
        # 4,根据用户数据获取用户对象
        user = User.objects.get(username=username)
        # 5,更新用户的邮箱验证状态
        user.email_active = True
        user.save()
        # 6,返回验证状态
        return Response({'email_active': user.email_active})


class UserLoginView(ObtainJSONWebToken):
    '''重写用户登录'''

    def post(self, request, *args, **kwargs):
        '''重写post方法'''
        # 不修改原有登陆业务逻辑
        response = super().post(request, *args, **kwargs)

        serializer = self.get_serializer(data=request.data)

        if serializer.is_valid():
            user = serializer.object.get('user') or request.user

            # 增加合并购物车操作
            response = merge_cart_cookie_to_redis(request, response, user)
            return response

        return response

